/**
 * <p>Title: MongoUtil.java</p>
 * <p>Description: </p>
 * <p>Company: www.huoyunren.com</p>
 * @author duanxiangyun
 * @date 2016年8月15日
 * @version 1.0
 */
package com.hxbd.test.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import org.bson.Document;
import org.bson.conversions.Bson;

import com.duan.test.utils.Excel.DataHandlers;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;

public class MongoUtil {

	private MongoDatabase db;
	private MongoClient mongo;

	public MongoUtil(String host, int port, String dbname) {
		mongo = new MongoClient(host, port);
		db = mongo.getDatabase(dbname);
	}

	public MongoUtil(String host, int port, String username, String pwd,
			String dbname) {
		String sURI = String.format("mongodb://%s:%s@%s:%d/", username, pwd,
				host, port);
		MongoClientURI uri = new MongoClientURI(sURI);
		mongo = new MongoClient(uri);
		db = mongo.getDatabase(dbname);
	}

	/**
	 * 从excel中插入数据(必须sheet名与表名一致)
	 * 
	 * @param filename
	 *            excel文件名(绝对路径名)
	 * @param sheet
	 *            sheet名
	 * @return
	 * @throws Exception 
	 */
	public MongoCollection<Document> insertMongoDataFromExcel(String filename,
			String sheet) throws Exception {
		Object[][] o = DataHandlers.getInstance(filename).getData(sheet, 0, -1,
				0, -1, true);
		MongoCollection<Document> c = db.getCollection(sheet);
		List<Document> list = new ArrayList<Document>();
		for (int i = 2; i < o.length; i++) {
			Document user = new Document();
			for (int j = 0; j < o[i].length; j++) {
				Object value = o[i][j].toString();
				String key = o[0][j].toString();
				String fomart = o[1][j].toString();
				if (value.toString().isEmpty()) {
					if (key.equalsIgnoreCase("createTime")
							|| key.equalsIgnoreCase("updateTime")) {
						if (!fomart.isEmpty() && isEnumDateformat(fomart)) {
							value = getNow(fomart);
						} else {
							value = new Date();
						}
						user.put(key, value);
					}
				} else {
					if (fomart.equalsIgnoreCase("int")) {
						value = Integer.parseInt(value.toString());
					} else if (fomart.equalsIgnoreCase("long")) {
						value = Long.parseLong(value.toString());
					} else if (fomart.equalsIgnoreCase("double")) {
						value = Double.parseDouble(value.toString());
					} else if (fomart.equalsIgnoreCase("boolean")) {
						value = Boolean.parseBoolean(value.toString());
					} else if (!fomart.isEmpty() && isEnumDateformat(fomart)) {
						value = StringToDate(value.toString(), fomart);
					} else {
						value = value.toString();
					}
					user.put(key, value);
				}
			}
			list.add(user);
		}
		c.insertMany(list);
		return c;
	}

	/**
	 * 字符串转时间格式
	 * 
	 * @param date
	 * @param dataformat
	 * @return
	 */
	public static Date StringToDate(String date, String dataformat) {
		SimpleDateFormat formatDate = new SimpleDateFormat(dataformat);
		Date time = null;
		try {
			time = formatDate.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return time;
	}

	/**
	 * 获得当前时间
	 * 
	 * @param dataformat
	 * @return
	 */
	private static Date getNow(String dataformat) {
		Date now = new Date();
		SimpleDateFormat formatDate = new SimpleDateFormat(dataformat);
		String time = null;
		time = formatDate.format(now);
		Date date = null;
		try {
			date = formatDate.parse(time);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return date;
	}

	public static Boolean isEnumDateformat(String format) {
		List<DateFormats> l = Arrays.asList(DateFormats.values());
		Boolean bol = false;
		for (DateFormats d : l) {
			if (d.getValue().equals(format)) {
				bol = true;
				break;
			}
		}
		return bol;
	}

	/**
	 * 删除某条数据
	 * 
	 * @param collection
	 * @param document
	 */
	public void insertOne(String collection, Document document) {
		db.getCollection(collection).insertOne(document);
	}

	/**
	 * 删除列表中数据
	 * 
	 * @param collection
	 * @param l
	 *            列表
	 */
	public void insertMany(String collection, List<Document> l) {
		db.getCollection(collection).insertMany(l);
	}

	/**
	 * 删除符合条件的多条数据
	 * 
	 * @param collection
	 * @param filter
	 */
	public void deleteMany(String collection, Bson filter) {
		db.getCollection(collection).deleteMany(filter);
	}

	/**
	 * 删除符合条件的一条数据
	 * 
	 * @param collection
	 * @param filter
	 */
	public void deleteOne(String collection, Bson filter) {
		db.getCollection(collection).deleteOne(filter);
	}

	/**
	 * 查询
	 * 
	 * @param collection
	 * @param filter
	 * @return
	 */
	public List<Document> find(String collection, Bson filter) {
		List<Document> list = new LinkedList<Document>();
		FindIterable<Document> fi = db.getCollection(collection).find(filter);
		MongoCursor<Document> cursor = fi.iterator();
		while (cursor.hasNext()) {
			list.add(cursor.next());
		}
		return list.size() > 0 ? list : null;
	}

	/**
	 * 查询多少条数据
	 * 
	 * @param collection
	 * @param filter
	 *            查询条件 Filter
	 * @param limit
	 *            查询多少条
	 * @return list
	 */
	public List<Document> find(String collection, Bson filter, int limit) {
		List<Document> list = new LinkedList<Document>();
		FindIterable<Document> fi = db.getCollection(collection).find(filter)
				.limit(limit);
		MongoCursor<Document> cursor = fi.iterator();
		while (cursor.hasNext()) {
			list.add(cursor.next());
		}
		return list.size() > 0 ? list : null;
	}

	/**
	 * 按页查询
	 * 
	 * @param collection
	 * @param filter
	 * @param orderBy
	 *            排序
	 * @param pageNum
	 * @param pageSize
	 * @return list
	 */
	public List<Document> find(String collection, Bson filter, Bson orderBy,
			int pageNum, int pageSize) {
		List<Document> list = new ArrayList<Document>();
		FindIterable<Document> fi = db.getCollection(collection).find(filter)
				.skip((pageNum - 1) * pageSize).limit(pageSize).sort(orderBy);
		MongoCursor<Document> cursor = fi.iterator();
		while (cursor.hasNext()) {
			list.add(cursor.next());
		}
		return list.size() > 0 ? list : null;
	}

	/**
	 * 更新
	 * 
	 * @param collection
	 * @param filter
	 *            要更新的数据查询规则
	 * @param update
	 *            更新的规则
	 */
	public void update(String collection, Bson filter, Bson update) {
		db.getCollection(collection).updateMany(filter, update);
	}

	/**
	 * 计数
	 * 
	 * @param collection
	 * @param filter
	 * @return
	 */
	public long count(String collection, Bson filter) {
		return db.getCollection(collection).count(filter);
	}

	public void close() {
		mongo.close();
	}

	// //查询出key字段,去除重复，返回值是{_id:value}形式的list
	// public List distinct(String collection, String fieldName, Bson filter) {
	// DistinctIterable<BsonValueCodec> d =
	// db.getCollection(collection).distinct(fieldName, filter,
	// BsonValueCodec.class);
	// List<BsonValueCodec> list = new ArrayList<BsonValueCodec>();
	// MongoCursor<BsonValueCodec> cursor = d.iterator();
	// while (cursor.hasNext()) {
	// list.add(cursor.next());
	// }
	// return list.size() > 0 ? list : null;
	// }

	public static void main(String[] args) {
		MongoUtil mongoutil = new MongoUtil(
				"dds-bp156bdc749ae6d42.mongodb.rds.aliyuncs.com",
				3717, "root", "iomFn2Yo8", "stats");
		System.out.println(StringToDate("20170517 00:00:00", "yyyyMMdd hh:mm:ss"));
		List<Document> l = mongoutil.find("truck_statistics",Filters.and(Filters.eq("periodType", "DAY"),Filters.gte("statDate", StringToDate("20170517 00:00:00", "yyyyMMdd hh:mm:ss"))));
	}
}
